﻿// page init
var user_agent = navigator.userAgent.toLowerCase(),
	is_safari_mac = (user_agent.indexOf("safari") > -1) && (user_agent.indexOf("mac") > -1),
	safari_version = 0;

if (is_safari_mac) {
	var re = new RegExp(/.*version\/([0-9]+)\..*/gi),
		match = re.exec(user_agent);
	if (match) safari_version = match[1];
}
// DEBUG
//console.log("safari_version: " + safari_version);


// Add window on-load event
if (typeof window.addLoadEvent == "undefined") {

	window.addLoadEvent = function(fn) {
		if (window.addEventListener) {
			window.addEventListener("load", fn, false);
		}
		else if (window.attachEvent) {
			window.attachEvent("onload", fn);
		}
		else {
			var fo = window.onload;
			if (typeof fo !== "function") {
				window.onload = fn;
			}
			else {
				window.onload = function() { fo(); fn(); }
			}
		}
	}
}


jQuery(function() {
	if ($.fn.superfish) {
		$('div.tabs .sf-menu').supersubs({
			minWidth: 12,	// minimum width of sub-menus in em units
			maxWidth: 27,	// maximum width of sub-menus in em units
			extraWidth: 1	// extra width can ensure lines don't sometimes turn over
							// due to slight rounding differences and font-family
		}).superfish({
			speed: 300
		});
	}

	// Tooltips
	$(".info").tooltip({
		showURL: false,
		track: true,
		fade: 150,
		top: 23,
		left: 0
	}).css("cursor", "pointer");

	$(".count-tooltip").tooltip({
		showURL: false,
		track: true,
		fade: 150,
		top: -100,
		left: -380,
		bodyHandler: function() {
			$("#tooltip").addClass("count-tooltip-wrapper");
			return $(this).find(".tooltip-simpletable").clone();
		}
	}).css("cursor", "pointer");

	$("input.text.cal").each(function(i, e) {
		$(e).width($(e).width() - 16);
	});


	// Dashboard calendar
	if ($.datepicker) {
		if ($("#calendar").length) {
			$("#calendar").datepicker({
				dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
				showOtherMonths: true
			});
		}

		$("input.text.cal").css("zIndex", 99)
			.datepicker({
				dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
				showOtherMonths: true
			});

		if ($("input.text.date").length) {
			$("input.text.date").datepicker({
				dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
				showOtherMonths: true
			});
		}

		if ($("input.text.calendar-date").length) {
			$("input.text.calendar-date").datepicker({
				dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
				showOtherMonths: true
			});
		}

		if ($("input.text.calendar-datetime").length) {
			$("input.text.calendar-datetime").datetimepicker({
				dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
				showOtherMonths: true
			});
		}
	}


	// Resize textbox inside table
	$(".textintable").each(function() {
		var el = $(this);
		el.width( el.parent().width() - (el.outerWidth() - el.width()) );
		//el.width(get_width_only(el.parent())).width(get_width_only(el));
	});

	// TODO: Was copied from the UX 11-21-12
	// Input enable button behavior
	$(".enable-btn").keyup(function() {
		var el = $(this),
			data = el.attr("data-enable").split(":");

		if (el.val() != "") {
			$("#" + data[0]).removeClass(data[2]).addClass(data[1]);
		}
		else {
			$("#" + data[0]).removeClass(data[1]).addClass(data[2]);
		}
	});


	// Progress bar fix
	//resize_progress_bar();
	//$(window).resize(resize_progress_bar);

	// show more options
	$(".table div.col1.error").showMoreOptions();

	$(".table div.title > .col1:last").css("borderRight", "none");
	$(".table div.line").each(function() {
		$(this).find("> .col1:last").css("borderRight", "none");
	});


	// Editable select
	init_editable_select();

	//normalize_cols_height($(".table-leads"));
	fix_table_cols_height($(".table"));
	// Contents height
	//content_max_height($(".dashboard"));
	//content_max_height($(".leads-view"));

	// Horizontal scroll
	hscroll_size();
	hscroll_resize_events();	// TODO: Was extended from UX 11-21-12
	$(window).resize(function() { hscroll_size(); hscroll_resize_events(); });

	// Disabler
	/*$("#toolbar1, #grouped-form1").disabler();
	// Filters init
	$(".filter-trigger").showFilter();*/

	$(".toolbar .filters a[href=#]").click(function() { return false; });

	// Append clear-search-button into searchboxs: #headerSearchInput, #SearchInput
	$(".search input.text:text, input.search:text").each(function(idx, el) {
		var el = $(el),
			pObj = el.parent(),
			cssVal = pObj.css("position");

		// Absolute position with relative parent element
		if (!cssVal || $.trim(cssVal).toLowerCase() != "relative") return;

		// Calculate the button position
		var rpos = 7,
			tpos = (el.outerHeight() - 17) / 2;

		cssVal = el.css("marginRight");
		// DEBUG
		// if (typeof console != "undefined") console.log("TextBox.search marginRight = " + cssVal);
		if (cssVal) {
			cssVal = cssVal.replace(/^[^\d]+/, "").replace(/[^\d]+$/, "");
			if (cssVal && !isNaN(cssVal = parseInt(cssVal))) {
				rpos += cssVal;
			}
		}

		var field_pos = el.offset(),
			parent_pos = pObj.offset();
		if (field_pos && !isNaN(field_pos.top) && parent_pos && !isNaN(parent_pos.top)) {
			tpos += field_pos.top - parent_pos.top;
		}

		var xbtn = $('<a href="#" class="btn btn-gray-x btn-clearsearch">Clear</a>')
			.css({
				position: "absolute",
				zIndex: 1,
				top: tpos,	//field_pos.top + ((el.outerHeight(true) - 25) / 2) + 5,
				right: rpos	//field_pos.left + el.outerWidth(true) - 20
			});

		xbtn.get(0).search_field = el;
		xbtn.click(function() {
			if (!this.search_field.is(":disabled")) {
				this.search_field.val("").focus();
			}
			return false;
		});

		/*$(window).bind("resize", function() {
			var field_pos = xbtn.get(0).search_field.offset();
			xbtn.css({
				top: field_pos.top + ((xbtn.get(0).search_field.outerHeight(true) - 25) / 2) + 5,
				left: field_pos.left + xbtn.get(0).search_field.outerWidth(true) - 20
			})
		});*/

		xbtn.insertAfter(el);
	});


	$("#row-sel-subindustry").hide();
	$("#sel-industry").change(function() {
		$.post(
			"ajax.php",
			{ industry: $(this).val() },
			function(data) {
				$("#row-sel-subindustry").hide();
				$("#sel-subindustry").html('<option id="">Select Sub-Industry</option>');

				var has_data = false;
				$(data).each(function(id, el) {
					has_data = true;
					$("#sel-subindustry").append($("<option />").attr("id", el.id).html(el.name));
				});

				if (has_data) $("#row-sel-subindustry").fadeIn(300);

				// refresh JCF
				var els = jcf.lib.queryBySelector(jcf.modules["select"].prototype.selector);
				for (var i = 0; i < els.length; i++) {
					if (typeof els[i].jcf != "undefined" && els[i].jcf) {
						els[i].jcf.buildDropdownOptions();
						els[i].jcf.refreshState();
					}
				}
			},
			"json");
	});

	// CSS Fixes
	if (is_safari_mac) {
		$(".toolbar .select-holder").css("marginBottom", "3px");
		$(".toolbar input.editable-select").css("height", "24px");
	}


	// TODO: May be added from UX 11-21-12
	//$("input[type=text].phone").phone_fields_init();

	initNavIndexes();
	setTimeout("initInputs()", 10);

	initSelectLine();
	//init_fancybox();

	// Force calling after Knockout binding event
	jcf.customForms.replaceAll();
	setTimeout("jcf.customForms.replaceAll()", 0);
	setTimeout("jcf.customForms.refreshAll()", 10);
});


$.fn.set_action_tooltip = function(opt) {
	var defaults = {
		width: 300,
		offset_x: 0,
		offset_y: 0,
		cancel_class: "",
		continue_class: ""
	};
	opt = $.extend(defaults, opt);

	$(this).click(function() {
		var el = $(this),
			msg = el.attr("title");
		if (!msg) return false;

		var btn_pos = el.offset();

		if (!$(".action-tooltip").length) {
			var ttip = $('<div class="action-tooltip" />').hide();
			$("body").append(ttip);

			ttip.append("<h4>" + msg + "</h4>")
				.append('<a href="#" class="' + opt.cancel_class + ' act-cancel">Cancel</a>')
				.append('<a href="#" class="' + opt.continue_class + ' act-continue">Continue</a>')
				.append('<span class="arr" />')
				.width(opt.width)
				.css({
					top: (btn_pos["top"]  - ttip.outerHeight(true) + opt.offset_y),
					left: (btn_pos["left"] - ttip.outerWidth(true) + el.outerWidth(true) + opt.offset_x)
				});

			ttip.find(".act-cancel").click(function() {
				ttip.fadeOut(300);
				return false;
			});

			ttip.find(".act-continue").click(function() {
				editLeadViewModel.DeleteAppointment();
				ttip.fadeOut(300);
				return false;
			});
		}
		else {
			var ttip = $(".action-tooltip").hide();
			ttip.find("h4").html(msg);
			ttip.css({
				top: (btn_pos["top"]  - ttip.outerHeight(true) + opt.offset_y),
				left: (btn_pos["left"] - ttip.outerWidth(true) + el.outerWidth(true) + opt.offset_x)
			});
		}

		ttip.fadeIn(300);
		return false;
	});


	// TODO: Is needed?
	// CSS Fixes
	if (is_safari_mac) {
		$(".toolbar .select-holder").css("marginBottom", "3px");
		$(".toolbar input.editable-select").css("height", "24px");
	}
};

function resize_progress_bar() {
	var pb = $("progress-bar");
	pb.width(pb.parent().width() - pb.parent().find(".progress-info").width() - 20);
}


var parent_extra_sum = 0;

function hscroll_size() {
	// Sum cols width and set it as .title and .line widths
	/*var sum = 0;
	$(".table-horscroll div.line:first").children().each(function() {
		sum += $(this).Outerwidth(true)
	});
	$(".table-horscroll div.title").width(sum + 10);
	$(".table-horscroll div.line").width(sum + 10);*/

	// If NOT full width layout then return
	if (!$(".full-width").length) return;

	var ths = $(".table-horscroll"),		// scrollable table
		ths_parent = ths.parent(),
		viewport_w = $(window).width(),		// Viewport or window width
		parent_w = ths_parent.width() - 1;	// Table parent width

	// Document min-width set for .full-width (liquid) pages
	var min_w = parseInt($(".full-width").css("minWidth"), 10);

	// Go up from the table to the root element getting borders, paddings and margins
	//var tmp_sum = 0;	// sum

	if (parent_extra_sum == 0) {
		var tmp_t = ths_parent;	// copy of ths_parent element

		while (tmp_t.parent().length) {
			//parent_extra_sum += sum_width_extras(tmp_t);
			parent_extra_sum += (tmp_t.outerWidth(true) - tmp_t.width());
			tmp_t = tmp_t.parent();
		}

		parent_extra_sum += sum_width_extras(ths) + 2;
		//parent_extra_sum += (ths.outerWidth(true) - ths.width()) + 2;
	}

	var tmp_sum = parent_extra_sum;
	// DEBUG
	//console.log("tmp_sum: " + tmp_sum);

	// Detects wether there's scroll by comparising viewport/doc widths
	var it_scrolls = $(window).height() < $(document).height();
	// DEBUG
	//console.log("it_scrolls: " + ((!it_scrolls) ? "false" : "true"));

	var parents_based_width = parent_w - sum_width_extras(ths);
	//var parents_based_width = parent_w - (ths.outerWidth(true) - ths.width());
	// DEBUG
	//console.log("parents_based_width: " + parents_based_width);

	// If it scroll and is not mac safari (floating scroll), sum scroll width.
	if (it_scrolls && !(is_safari_mac && safari_version >= 6)) {
		tmp_sum += 17;
	}
	// DEBUG
	//console.log("tmp_sum: " + tmp_sum + ", viewport_w: " + viewport_w);

	var vp_based_width = viewport_w - tmp_sum;
	// DEBUG
	//console.log("vp_based_width: " + vp_based_width);

	if ($.browser.msie && $.browser.msie && parseInt($.browser.version, 10) <= 8)
		vp_based_width += 21;

	if (vp_based_width <= 990) vp_based_width = 990;
	// DEBUG
	//console.log("vp_based_width: " + vp_based_width);

	ths.width(vp_based_width + 2);
	//ths.css("overflow", "scroll");	// TODO: Modify the CSS class ".table-horscroll" in global.css file instead of coding here
}

function hscroll_resize_events() {
	// Group events
	var group = $(".events"),
		viewport_group = $(window).width(),
		group_based_width = viewport_group - 460;
	// DEBUG
	//console.log("window: " + viewport_group);

	if (group_based_width <= 610) group_based_width = 610;
	// DEBUG
	//console.log("short_based_width: " + group_based_width);
	group.width(group_based_width);

	// Short title
	var ths = $(".shortdesc"),
		viewport_w = $(window).width(),
		vp_based_width = viewport_w - 825;
	// DEBUG
	//console.log("window: " + viewport_w);

	if (vp_based_width <= 270) vp_based_width = 270;
	// DEBUG
	//console.log("short_based_width: " + vp_based_width);
	ths.width(vp_based_width);
}


function get_width_only(el) {
	var w = parseInt(el.width(), 10)
		- parseInt(el.css("marginLeft"), 10)
		- parseInt(el.css("marginRight"), 10)
		- parseInt(el.css("paddingLeft"), 10)
		- parseInt(el.css("paddingRight"), 10)
		- parseInt(el.css("borderLeftWidth"), 10)
		- parseInt(el.css("borderRightWidth"), 10);

	return w;
}

function sum_width_extras(el) {
	var tmp_s = parseInt(el.css("paddingLeft"), 10)
		+ parseInt(el.css("paddingRight"), 10)
		+ parseInt(el.css("marginLeft"), 10)
		+ parseInt(el.css("marginRight"), 10)
		+ parseInt(el.css("borderLeftWidth"), 10)
		+ parseInt(el.css("borderRightWidth"), 10);
	return tmp_s;
}

function init_editable_select() {
	if (!$(".editable-select").length) return;

	$(".editable-select").editableSelect({
		bg_iframe: true,
		case_sensitive: false,
		items_then_scroll: 10
	});
}

$.fn.showPopup = function(opt) {
	var defaults = {
		width: 400,
		opacity: 0.6,
		overlayColor: "#11619d",
		padding: 0,
		closeButton: false
	};
	opt = $.extend(defaults, opt);

	var el = $(this);
	$(document).ready(function() {
		$.fancybox(el, {
			padding: opt.padding,
			closeBtn: opt.closeButton,
			width: opt.width,
			minWidth: opt.width,
			maxWidth: opt.width,
			helpers: {
				overlay: {
					opacity: opt.opacity,
					css: { "background-color": opt.overlayColor }
				}
			},
			beforeClose: function() { if (!opt.closeButton) return false; }
		});
	});
};

$.fn.showMoreOptions = function() {
	var btn = $('<a href="#" class="btn btn-downarrow">More</a>');
	btn.bind("click", function() {
		$(".more-options").hide();

		$(this).parent().find(".more-options").fadeIn(300);
		return false;
	});

	var mouse_is_inside = false,
		mo = $('<span class="more-options"><a href="#">Edit</a><a href="#">Clear Contents</a></span>');

	mo.hover(function() {
		mouse_is_inside = true;
	}, function() {
		mouse_is_inside = false;
	});

	$(this).append(btn).append(mo);

	$(document).click(function() {
		if (!mouse_is_inside) { $(".more-options").fadeOut(300); }
	});
};

$.fn.showFilter = function() {
	var mouse_is_inside = false;

	$(this).click(function() {
		var curr_el = $(this),
			wrapper = curr_el.parent().parent(),
			link = curr_el.parent();

		mouse_is_inside = true;

		if (wrapper.hasClass("active")) {
			wrapper.removeClass("active");
		}
		else {
			$(".filter-wrapper.active").removeClass("active");
			wrapper.addClass("active");
		}

		$(wrapper, link).hover(function() {
			mouse_is_inside = true;
		}, function() {
			mouse_is_inside = false;
		});

		return false;
	});

	$(document).click(function() {
		if (!mouse_is_inside) { $(".filter-wrapper.active").removeClass("active"); }
	});
};

$.fn.disabler = function(opt) {
	var opt = $.extend({ conditions: [] }, opt);

	this.each(function(eid, el) {

		// Function that resizes the overlay
		var resizeIt = function(_disabler, el) {
			/*var _height = parseInt(el.height(), 10);
			_height += parseInt(el.css("paddingTop"), 10) + parseInt(el.css("paddingBottom"), 10);
			_height += parseInt(el.css("marginTop"), 10) + parseInt(el.css("marginBottom"), 10);
			_height += parseInt(el.css("borderTopWidth"), 10) + parseInt(el.css("borderBottomWidth"), 10);

			var _width = parseInt(el.width(), 10);
			_width += parseInt(el.css("paddingLeft"), 10) + parseInt(el.css("paddingRight"), 10);
			_width += parseInt(el.css("marginLeft"), 10) + parseInt(el.css("marginRight"), 10);
			_width += parseInt(el.css("borderLeftWidth"), 10) + parseInt(el.css("borderRightWidth"), 10);*/

			var _height = el.outerHeight(true),
				_width = el.outerWidth(true);

			_disabler.width(_width - 2).height(_height);
		}

		// wrapping element
		el = $(el);
		el.css("position", "relative");

		// Overlay obj
		var _disabler = $('<span class="disabler"></span>');
		// Style the overlay
		_disabler.css({
			display: "none",
			position: "absolute",
			top: 0,
			left: 0,
			background: "#fff",
			opacity: 0.7,
			zIndex: 9999
		});
		// Resize the overlay
		resizeIt(_disabler, el);
		// Add the overlay to the wrapping element
		el.append(_disabler);
		// Fade in the overlay
		_disabler.fadeIn(400);

		// Resize the overlay on windows resize
		$(window).resize(function() { resizeIt(_disabler, el) });

		// TODO: Added from the UX 11-21-12
		$.each(opt.conditions, function(n, i) {
			if (i.selector == "select") {
				var select_items = i.items;
				// Go through select items. Each one of them has to have a value set in order to enable the target
				$.each(select_items, function(it_n, it_i) {
					var s_item = $("#" + it_i);	// This is a select
					// DEBUG
					//console.log(s_item);
					s_item.change(function() {	// on item change
						// DEBUG
						//console.log("changed!");
						var enable_it = true;
						$.each(select_items, function(ic_n, ic_i) {
							var ic_i = $("#" + ic_i);
							// DEBUG
							//console.log(ic_i);
							if (ic_i.val() == "") enable_it = false;
						});

						if (enable_it) {
							_disabler.fadeOut(400);
							// DEBUG
							//console.log(_disabler);
						}
					});
				});
			}
		});

	});
};

// Waiting...
$.fn.waiting = function() {
	this.each(function(eid, el) {

		// Function that resizes the overlay
		var resizeIt = function(_waiting, el) {
			/*var _height = parseInt(el.height(), 10);
			_height += parseInt(el.css("paddingTop"), 10) + parseInt(el.css("paddingBottom"), 10);
			_height += parseInt(el.css("marginTop"), 10) + parseInt(el.css("marginBottom"), 10);
			_height += parseInt(el.css("borderTopWidth"), 10) + parseInt(el.css("borderBottomWidth"), 10);

			var _width = parseInt(el.width(), 10);
			_width += parseInt(el.css("paddingLeft"), 10) + parseInt(el.css("paddingRight"), 10);
			_width += parseInt(el.css("marginLeft"), 10) + parseInt(el.css("marginRight"), 10);
			_width += parseInt(el.css("borderLeftWidth"), 10) + parseInt(el.css("borderRightWidth"), 10);*/

			var _height = el.outerHeight(true),
				_width = el.outerWidth(true);

			_waiting.width(_width - 2).height(_height);
		}

		// wrapping element
		el = $(el);
		el.css("position", "relative");

		// Overlay obj
		var _waiting = $('<span class="waiting"></span>');
		// Style the overlay
		_waiting.css({
			display: "none",
			position: "absolute",
			top: 0,
			left: 0,
			background: "#11619D",
			opacity: 0.4,
			zIndex: 99
		});
		// Resize the overlay
		resizeIt(_waiting, el);
		// Add the overlay to the wrapping element
		el.append(_waiting);
		// Fade in the overlay
		_waiting.fadeIn(400);

		// Resize the overlay on windows resize
		$(window).resize(function() { resizeIt(_waiting, el) });
	});
};

$(window).resize(function() {
	//normalize_cols_height($(".table-leads"));
	fix_table_cols_height($(".table"));
	content_max_height($(".dashboard"));
	content_max_height($(".leads-view"));
});

// Set content height max possible height
function content_max_height(page) {
	if (page.length) {
		var header_height = $("#header").height() + 23,
			vp_height = $(window).height(),
			doc_height = $(document).height(),
			pan_height = (vp_height - header_height) - 26;

		if (doc_height <= vp_height)
			$(".content").height(pan_height);
	}
}

// Normalize cols height
/*function normalize_cols_height(table) {
	var title_h = table.find("div.title:first").height();
	table.find("div.title:first > div").each(function(idx, el) {
		// DEBUG
		//console.log($(el).padding());
		$(el).find(".w").height(title_h - 20);
	});

	table.find("div.line").each(function(idx_line, el_line) {
		var line_h = $(el_line).height() - 20;

		$(el_line).find("> div").each(function(idx_col, el_col) {
			$(el_col).find(".w").css("minHeight", line_h);
		});
	});
}*/

// Normalize cols height
function fix_table_cols_height(tables) {
	tables.each(function(idx, table) {
		table = $(table);

		// Add table-ignore to exclude it from this function
		if (table.hasClass("table-fixed") || !table.is(":visible")) return;
		// DEBUG
		//if (typeof console != "undefined") console.log("Normalize cols height of the table: " + table.attr("id"));

		//--- Fix header row height
		var title_r = table.find("div.title:first");

		// Reset first
		title_r.find("> .col1, > .col1 .w").css("minHeight", "");
		var title_h = title_r.height("").height();
		// DEBUG
		//if (typeof console != "undefined") console.log("Header row height: " + title_h);

		if (title_h == 0) {
			title_r.find("> .col1").each(function() {
				var col_h = $(this).outerHeight(true);
				if (col_h > title_h) title_h = col_h;
			});
			title_r.height(title_h);
		}

		title_r.find("> .col1").each(function() {
			var $el  = $(this),
				el_w = $el.find(".w");

			if (el_w.length) {
				var extra = el_w.outerHeight(true) - el_w.height();
				el_w.css("minHeight", (title_h - extra));
			}
			else {
				var extra = $el.outerHeight(true) - $el.height();
				$el.css("minHeight", (title_h - extra));
			}
		});

		//--- Fix each table row height
		$("> div.line, > div > div.line, > div > div > div.line", table).each(function() {
			var line_r = $(this);

			// Reset first
			line_r.find("> .col1, > .col1 .w").css("minHeight", "");
			var line_h = line_r.height("").height();

			if (line_h == 0) {
				line_r.find("> .col1").each(function() {
					var col_h = $(this).outerHeight(true);
					if (col_h > line_h) line_h = col_h;
				});
				line_r.height(line_h);
			}

			line_r.find("> .col1").each(function() {
				var el_col = $(this),
					el_col_w = el_col.find(".w");

				if (el_col_w.length) {
					var extra = el_col_w.outerHeight(true) - el_col_w.height();
					el_col_w.css("minHeight", (line_h - extra));
				}
				else {
					var extra = el_col.outerHeight(true) - el_col.height();
					el_col.css("minHeight", (line_h - extra));
				}
			});
		});

	});// end each
}


// Fancybox set up
function init_fancybox() {
	if ($("#popup-deleteusers").length) {
		$.fancybox($("#popup-deleteusers"), {
			padding: 0,
			closeBtn: false,
			helpers: {
				overlay: {
					opacity: 0.8,
					css: { "background-color": "#11619d" }
				}
			},
			beforeClose: function() {
				return false;
			}
		});
	}

	if ($("#popup-processing").length) {
		$.fancybox($("#popup-processing"), {
			padding: 0,
			closeBtn: false,
			helpers: {
				overlay: {
					opacity: 0.8,
					css: { "background-color": "#11619d" }
				}
			},
			beforeClose: function() {
				return false;
			}
		});
	}

	if ($("#popup-onlyoneuser").length) {
		$.fancybox($("#popup-onlyoneuser"), {
			padding: 0,
			closeBtn: false,
			helpers: {
				overlay: {
					opacity: 0.8,
					css: { "background-color": "#11619d" }
				}
			},
			beforeClose: function() {
				return false;
			}
		});
	}

	// TODO: May need to initialize fancybox for classes:
	//	'.show-setup-process', '.show-setup-process-full'
}

// init select line
function initSelectLine() {
	var selectedClass = "selected-line";

	$(".table").each(function() {
		$("> div.line, > div > div.line, > div > div > div.line", this).each(function() {
			var line = $(this),
				chBox = line.find("> .col1 input:checkbox");

			if (chBox.length == 1) {	// TODO: When a table-row has only 1 checkbox
				if (chBox.get(0).checked) line.addClass(selectedClass);
				else line.removeClass(selectedClass);

				chBox.bind("change", function() {
					if (chBox.get(0).checked) line.addClass(selectedClass);
					else line.removeClass(selectedClass);
				});
			}
		});
	});
}

// initNavIndexes()
function initNavIndexes() {
	var nav = document.getElementById("steps");
	if (nav && typeof nav.getElementsByTagName != "undefined") {

		var lis = nav.getElementsByTagName("li");
		for (var i = 0; i < lis.length; i++) {
			//lis[i].style.zIndex = i + 1;
			lis[i].style.zIndex = lis.length - i;
		}
	}
}

// clear inputs on focus
function initInputs() {
	// replace options
	var opt = {
		clearInputs: true,
		clearTextareas: true,
		clearPasswords: true
	};
	// collect all items
	var inputs = [].concat(
		PlaceholderInput.convertToArray(document.getElementsByTagName("input")),
		PlaceholderInput.convertToArray(document.getElementsByTagName("textarea"))
	);
	// apply placeholder class on inputs
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].className.indexOf("default") < 0) {
			var inputType = PlaceholderInput.getInputType(inputs[i]);
			if ((opt.clearInputs && inputType === "text") ||
				(opt.clearTextareas && inputType === "textarea") ||
				(opt.clearPasswords && inputType === "password")) {

				new PlaceholderInput({
					element: inputs[i],
					wrapWithElement: false,
					showUntilTyping: false,
					getParentByClass: false,
					placeholderAttr: "value",
					keepOrigValueOnFocus: true
				});
			}
		}
	}
}

// input type placeholder class
; (function() {
	PlaceholderInput = function() {
		this.options = {
			element: null,
			showUntilTyping: false,
			wrapWithElement: false,
			getParentByClass: false,
			placeholderAttr: "value",
			inputFocusClass: "focus",
			inputActiveClass: "text-active",
			parentFocusClass: "parent-focus",
			parentActiveClass: "parent-active",
			labelFocusClass: "label-focus",
			labelActiveClass: "label-active",
			fakeElementClass: "input-placeholder-text",
			keepOrigValueOnFocus: true,
			// TODO: Ignores CSS classes for PlaceholderInput
			classNameHaveDefaultValue: /(?:^|\s)(?:phone\-?ext|search)/i
		}
		this.init.apply(this, arguments);
	}
	PlaceholderInput.convertToArray = function(collection) {
		var arr = [];
		for (var i = 0, ref = arr.length = collection.length; i < ref; i++) {
			arr[i] = collection[i];
		}
		return arr;
	}
	PlaceholderInput.getInputType = function(input) {
		return (!input) ? null
			: ((typeof input.type != "undefined" && input.type) ? input.type.toLowerCase()
			: ((typeof input.tagName != "undefined" && input.tagName) ? input.tagName.toLowerCase() : null));
	}
	PlaceholderInput.prototype = {
		init: function(opt) {
			this.setOptions(opt);
			if (this.element && this.element.PlaceholderInst) {
				this.element.PlaceholderInst.refreshClasses();
			}
			else {
				this.element.PlaceholderInst = this;
				if (this.elementType == "text" || this.elementType == "password" || this.elementType == "textarea") {
					this.initElements();
					this.attachEvents();
					this.refreshClasses();
				}
			}
		},
		setOptions: function(opt) {
			for (var p in opt) {
				if (opt.hasOwnProperty(p)) {
					this.options[p] = opt[p];
				}
			}
			if (this.options.element) {
				this.element = this.options.element;
				this.elementType = PlaceholderInput.getInputType(this.element);
				this.wrapWithElement = ((this.elementType === "password" && this.options.showUntilTyping) ? true : this.options.wrapWithElement);

				var hasDefaultVal = this.options.classNameHaveDefaultValue.test(this.element.className),
					defaultVal = (this.options.placeholderAttr == "value" && this.element.defaultValue)
						? this.element.defaultValue : this.element.getAttribute(this.options.placeholderAttr);
				if (!defaultVal && !hasDefaultVal) defaultVal = this.element.value;
				//
				this.setOrigValue(defaultVal);
				this.keepOrigValueOnFocus = (!hasDefaultVal ? this.options.keepOrigValueOnFocus : false);
			}
		},
		setOrigValue: function(value) {
			// DEBUG
			//if (typeof console != "undefined") console.log("PlaceholderInput.setOrigValue(), value = " + value);
			this.origValue = (typeof value === "undefined" || value === null) ? "" : value;
		},
		initElements: function() {
			// create fake element if needed
			if (this.wrapWithElement) {
				this.element.value = "";
				this.element.removeAttribute(this.options.placeholderAttr);
				this.fakeElement = document.createElement("span");
				this.fakeElement.className = this.options.fakeElementClass;
				this.fakeElement.innerHTML += this.origValue;
				this.fakeElement.style.color = getStyle(this.element, "color");
				this.fakeElement.style.position = "absolute";
				this.element.parentNode.insertBefore(this.fakeElement, this.element);
			}
			// get input label
			if (this.element.id) {
				this.labels = document.getElementsByTagName("label");
				for (var i = 0; i < this.labels.length; i++) {
					if (this.labels[i].htmlFor === this.element.id) {
						this.labelFor = this.labels[i];
						break;
					}
				}
			}
			// get parent node (or parentNode by className)
			this.elementParent = this.element.parentNode;
			if (typeof this.options.getParentByClass === "string") {
				var el = this.element;
				while (el.parentNode) {
					if (hasClass(el.parentNode, this.options.getParentByClass)) {
						this.elementParent = el.parentNode;
						break;
					}
					else {
						el = el.parentNode;
					}
				}
			}
		},
		attachEvents: function() {
			this.element.onfocus = bindScope(this.focusHandler, this);
			this.element.onblur = bindScope(this.blurHandler, this);
			if (this.options.showUntilTyping) {
				this.element.onkeydown = bindScope(this.typingHandler, this);
				this.element.onpaste = bindScope(this.typingHandler, this);
			}
			if (this.wrapWithElement) this.fakeElement.onclick = bindScope(this.focusSetter, this);
		},
		togglePlaceholderText: function(state) {
			if (this.wrapWithElement) {
				this.fakeElement.style.display = (!state) ? "none" : "";
			}
			else if (!this.keepOrigValueOnFocus) {
				this.element.value = (!state) ? "" : this.origValue;
			}
		},
		focusSetter: function() {
			this.element.focus();
		},
		focusHandler: function() {
			this.focused = true;
			if (!this.element.value || this.element.value === this.origValue) {
				if (!this.options.showUntilTyping) {
					this.togglePlaceholderText(false);
				}
			}
			this.refreshClasses();
		},
		blurHandler: function() {
			this.focused = false;
			if (!this.element.value || this.element.value === this.origValue) {
				this.togglePlaceholderText(true);
			}
			this.refreshClasses();
		},
		typingHandler: function() {
			setTimeout(bindScope(function() {
				if (this.element.value) {
					this.togglePlaceholderText(false);
					this.refreshClasses();
				}
			}, this), 10);
		},
		refreshClasses: function() {
			this.textActive = this.focused || (!!this.element.value && this.element.value !== this.origValue);
			this.setStateClass(this.element, this.options.inputFocusClass, this.focused);
			this.setStateClass(this.elementParent, this.options.parentFocusClass, this.focused);
			this.setStateClass(this.labelFor, this.options.labelFocusClass, this.focused);
			this.setStateClass(this.element, this.options.inputActiveClass, this.textActive);
			this.setStateClass(this.elementParent, this.options.parentActiveClass, this.textActive);
			this.setStateClass(this.labelFor, this.options.labelActiveClass, this.textActive);
		},
		setStateClass: function(el, cls, state) {
			if (!el) return;
			else if (state) addClass(el, cls);
			else removeClass(el, cls);
		}
	}

	// utility functions
	function hasClass(el, cls) {
		return el.className ? el.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)")) : false;
	}
	function addClass(el, cls) {
		if (!hasClass(el, cls)) el.className += " " + cls;
	}
	function removeClass(el, cls) {
		if (hasClass(el, cls)) { el.className = el.className.replace(new RegExp("(\\s|^)" + cls + "(\\s|$)"), " "); }
	}
	function bindScope(f, scope) {
		return function() { return f.apply(scope, arguments) }
	}
	function getStyle(el, prop) {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			return document.defaultView.getComputedStyle(el, null)[prop];
		}
		else if (el.currentStyle) {
			return el.currentStyle[prop];
		}
		else {
			return el.style[prop];
		}
	}
} ());

/*
* JavaScript Custom Forms 1.4.1
*/
jcf = {
	// global options
	modules: {},
	plugins: {},
	baseOptions: {
		useNativeDropOnMobileDevices: true,
		unselectableClass: "jcf-unselectable",
		labelActiveClass: "jcf-label-active",
		labelDisabledClass: "jcf-label-disabled",
		classPrefix: "jcf-class-",
		hiddenClass: "jcf-hidden",
		focusClass: "jcf-focus",
		wrapperTag: "div"
	},
	// replacer function
	customForms: {
		setOptions: function(obj) {
			for (var p in obj) {
				if (obj.hasOwnProperty(p) && typeof obj[p] === "object") {
					jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]);
				}
			}
		},
		replaceAll: function() {
			jcf.customForms.replaceElement("*");
		},
		replaceElement: function(elId) {
			if (typeof elId == "undefined" || !elId) elId = "*";

			for (var k in jcf.modules) {
				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
				for (var i = 0; i < els.length; i++) {
					//
					if (elId == "*" || els[i].id == elId) {
						if (typeof els[i].jcf != "undefined" && els[i].jcf) {
							// refresh form element state
							els[i].jcf.refreshState();
						}
						else {
							// replace form element
							if (!jcf.lib.hasClass(els[i], "default") && jcf.modules[k].prototype.checkElement(els[i])) {
								new jcf.modules[k]({ replaces: els[i] });
							}
						}

						if (elId != "*") return;
					}
				}
			}
		},
		refreshAll: function() {
			for (var k in jcf.modules) {
				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
				for (var i = 0; i < els.length; i++) {
					if (els[i].jcf) {
						// refresh form element state
						els[i].jcf.refreshState();
					}
				}
			}
		},
		refreshElement: function(obj) {
			if (obj && typeof obj.jcf != "undefined" && obj.jcf) {
				obj.jcf.refreshState();
			}
		},
		destroyAll: function(keepSelectedIndex) {
			for (var k in jcf.modules) {
				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
				for (var i = 0; i < els.length; i++) {
					if (els[i].jcf) {
						if (typeof keepSelectedIndex == "undefined" || !keepSelectedIndex) els[i].jcf.destroy();
						else els[i].jcf.destroy(keepSelectedIndex);
					}
				}
			}
		}
	},
	// detect device type
	isTouchDevice: (function() {
		try {
			return ("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch;
		} catch (e) {
			return false;
		}
	} ()),
	// define base module
	setBaseModule: function(obj) {
		jcf.customControl = function(opt) {
			this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt);
			this.init();
		}
		for (var p in obj) {
			jcf.customControl.prototype[p] = obj[p];
		}
	},
	// add module to jcf.modules
	addModule: function(obj) {
		if (obj.name) {
			// create new module proto class
			jcf.modules[obj.name] = function() {
				jcf.modules[obj.name].superclass.constructor.apply(this, arguments);
			}
			jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl);
			for (var p in obj) {
				jcf.modules[obj.name].prototype[p] = obj[p]
			}
			// on create module
			jcf.modules[obj.name].prototype.onCreateModule();
			// make callback for exciting modules
			for (var mod in jcf.modules) {
				if (jcf.modules[mod] != jcf.modules[obj.name]) {
					jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]);
				}
			}
		}
	},
	// add plugin to jcf.plugins
	addPlugin: function(obj) {
		if (obj && obj.name) {
			jcf.plugins[obj.name] = function() {
				this.init.apply(this, arguments);
			}
			for (var p in obj) {
				jcf.plugins[obj.name].prototype[p] = obj[p];
			}
		}
	},
	// miscellaneous init
	init: function() {
		this.eventPress = this.isTouchDevice ? "touchstart" : "mousedown";
		this.eventMove = this.isTouchDevice ? "touchmove" : "mousemove";
		this.eventRelease = this.isTouchDevice ? "touchend" : "mouseup";
		return this;
	},
	initStyles: function() {
		// create <style> element and rules
		var head = document.getElementsByTagName("head")[0],
			style = document.createElement("style"),
			rules = document.createTextNode("." + jcf.baseOptions.unselectableClass
				+ "{ -moz-user-select:none; -webkit-tap-highlight-color:rgba(255,255,255,0); -webkit-user-select:none; user-select:none; }");

		// append style element
		style.type = "text/css";
		if (style.styleSheet) {
			style.styleSheet.cssText = rules.nodeValue;
		}
		else {
			style.appendChild(rules);
		}
		head.appendChild(style);
	}
}.init();

/*
* Custom Form Control prototype
*/
jcf.setBaseModule({
	init: function() {
		if (this.options.replaces) {
			this.realElement = this.options.replaces;
			this.realElement.jcf = this;
			this.replaceObject();
		}
	},
	defaultOptions: {
		// default module options (will be merged with base options)
	},
	checkElement: function(el) {
		return true; // additional check for correct form element
	},
	replaceObject: function() {
		this.createWrapper();
		this.attachEvents();
		this.fixStyles();
		this.setupWrapper();
	},
	createWrapper: function() {
		this.fakeElement = jcf.lib.createElement(this.options.wrapperTag);
		this.labelFor = jcf.lib.getLabelFor(this.realElement);
		jcf.lib.disableTextSelection(this.fakeElement);
		jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix));
		jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass);
	},
	attachEvents: function() {
		jcf.lib.event.add(this.realElement, "focus", this.onFocusHandler, this);
		jcf.lib.event.add(this.realElement, "blur", this.onBlurHandler, this);
		jcf.lib.event.add(this.fakeElement, "click", this.onFakeClick, this);
		jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this);
		jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this);

		if (this.labelFor) {
			this.labelFor.jcf = this;
			jcf.lib.event.add(this.labelFor, "click", this.onFakeClick, this);
			jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this);
			jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this);
		}
	},
	fixStyles: function() {
		// hide mobile webkit tap effect
		if (jcf.isTouchDevice) {
			var tapStyle = "rgba(255,255,255,0)";
			this.realElement.style.webkitTapHighlightColor = tapStyle;
			this.fakeElement.style.webkitTapHighlightColor = tapStyle;
			if (this.labelFor) {
				this.labelFor.style.webkitTapHighlightColor = tapStyle;
			}
		}
	},
	setupWrapper: function() {
		// implement in subclass
	},
	refreshState: function() {
		// implement in subclass
	},
	destroy: function(keepSelectedIndex) {
		if (this.fakeElement) {
			if (this.fakeElement.parentNode) {
				this.fakeElement.parentNode.removeChild(this.fakeElement);
			}
			delete this.fakeElement;
		}
		jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);

		// Reset selected index of the rebinded dropdownbox
		if (typeof this.realElement.selectedIndex != "undefined"
			&& (typeof keepSelectedIndex == "undefined" || !keepSelectedIndex)) {

			this.realElement.selectedIndex = 0;
		}
		// Remove dropdown data
		if (this.selectDrop) {
			if (this.selectDrop.parentNode) {
				this.selectDrop.parentNode.removeChild(this.selectDrop);
			}
			delete this.selectDrop;
		}
		if (typeof this.origSelectedIndex != "undefined") {
			delete this.origSelectedIndex;
		}

		delete this.realElement.jcf;
		delete this.realElement;
	},
	onFocus: function() {
		// emulated focus event
		jcf.lib.addClass(this.fakeElement, this.options.focusClass);
	},
	onBlur: function(cb) {
		// emulated blur event
		jcf.lib.removeClass(this.fakeElement, this.options.focusClass);
	},
	onFocusHandler: function() {
		// handle focus loses
		if (this.focused) return;
		this.focused = true;

		// handle touch devices also
		if (jcf.isTouchDevice) {
			if (jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) {
				jcf.focusedInstance.onBlur();
				jcf.focusedInstance.realElement.blur();
			}
			jcf.focusedInstance = this;
		}
		this.onFocus.apply(this, arguments);
	},
	onBlurHandler: function() {
		// handle focus loses
		if (!this.pressedFlag) {
			this.focused = false;
			this.onBlur.apply(this, arguments);
		}
	},
	onFakeClick: function() {
		if (jcf.isTouchDevice) {
			this.onFocus();
		}
		else if (!this.realElement.disabled) {
			this.realElement.focus();
		}
	},
	onFakePressed: function(e) {
		this.pressedFlag = true;
	},
	onFakeReleased: function() {
		this.pressedFlag = false;
	},
	onCreateModule: function() {
		// implement in subclass
	},
	onModuleAdded: function(module) {
		// implement in subclass
	},
	onControlReady: function() {
		// implement in subclass
	}
});

/*
* JCF Utility Library
*/
jcf.lib = {
	bind: function(func, scope) {
		return function() {
			return func.apply(scope, arguments);
		}
	},
	browser: (function() {
		var ua = navigator.userAgent.toLowerCase(),
			res = {},
			match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
				/(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];

		res[match[1]] = true;
		res.version = match[2] || "0";
		res.safariMac = ua.indexOf("mac") != -1 && ua.indexOf("safari") != -1;
		return res;
	})(),
	getOffset: function(obj) {
		if (obj.getBoundingClientRect) {
			var scrollLeft = (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft),
				scrollTop = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop),
				clientLeft = (document.documentElement.clientLeft || document.body.clientLeft || 0),
				clientTop = (document.documentElement.clientTop || document.body.clientTop || 0);
			return {
				top: Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop),
				left: Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft)
			};
		}
		else {
			var posLeft = 0, posTop = 0;
			while (obj.offsetParent) {
				posLeft += obj.offsetLeft;
				posTop += obj.offsetTop;
				obj = obj.offsetParent;
			}
			return { top: posTop, left: posLeft };
		}
	},
	getScrollTop: function() {
		return (typeof window.pageYOffset != "undefined") ? window.pageYOffset
			: ((document.documentElement && document.documentElement.clientHeight)
			? document.documentElement.scrollTop : document.body.scrollTop);
	},
	getScrollLeft: function() {
		return (typeof window.pageXOffset != "undefined") ? window.pageXOffset
			: ((document.documentElement && document.documentElement.clientWidth)
			? document.documentElement.scrollLeft : document.body.scrollLeft);
	},
	getWindowWidth: function() {
		return (document.compatMode && document.compatMode.toLowerCase() == "css1compat")
			? document.documentElement.clientWidth : document.body.clientWidth;
	},
	getWindowHeight: function() {
		return (document.compatMode && document.compatMode.toLowerCase() == "css1compat")
			? document.documentElement.clientHeight : document.body.clientHeight;
	},
	getStyle: function(el, prop) {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			return document.defaultView.getComputedStyle(el, null)[prop];
		}
		else if (el.currentStyle) {
			return el.currentStyle[prop];
		}
		else {
			return el.style[prop];
		}
	},
	getParent: function(obj, selector) {
		while (obj.parentNode && obj.parentNode != document.body) {
			if (obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) {
				return obj.parentNode;
			}
			obj = obj.parentNode;
		}
		return false;
	},
	isParent: function(child, parent) {
		while (child.parentNode) {
			if (child.parentNode === parent) {
				return true;
			}
			child = child.parentNode;
		}
		return false;
	},
	getLabelFor: function(object) {
		if (jcf.lib.getParent(object, "label")) {
			return object.parentNode;
		}
		else if (object.id) {
			return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0];
		}
	},
	disableTextSelection: function(el) {
		if (typeof el.onselectstart !== "undefined") {
			el.onselectstart = function() { return false };
		}
		else if (window.opera) {
			el.setAttribute("unselectable", "on");
		}
		else {
			jcf.lib.addClass(el, jcf.baseOptions.unselectableClass);
		}
	},
	enableTextSelection: function(el) {
		if (typeof el.onselectstart !== "undefined") {
			el.onselectstart = null;
		}
		else if (window.opera) {
			el.removeAttribute("unselectable");
		}
		else {
			jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass);
		}
	},
	queryBySelector: function(selector, scope) {
		return this.getElementsBySelector(selector, scope);
	},
	prevSibling: function(node) {
		while (node = node.previousSibling) if (node.nodeType == 1) break;
		return node;
	},
	nextSibling: function(node) {
		while (node = node.nextSibling) if (node.nodeType == 1) break;
		return node;
	},
	fireEvent: function(element, event) {
		// DEBUG
		//if (typeof console != "undefined") console.log("Fire event: '" + event + "' on the element: " + element.id);

		// TODO: Trigger event via jQuery
		if (typeof jQuery != "undefined" && jQuery) {
			jQuery(element).trigger(event);
		}
		else if (document.createEventObject) {
			var evt = document.createEventObject();
			return element.fireEvent("on" + event, evt)
		}
		else if (document.createEvent) {
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent(event, true, true);
			return !element.dispatchEvent(evt);
		}
	},
	isParent: function(p, c) {
		while (c.parentNode) {
			if (p == c) {
				return true;
			}
			c = c.parentNode;
		}
		return false;
	},
	inherit: function(Child, Parent) {
		var F = function() { }
		F.prototype = Parent.prototype
		Child.prototype = new F()
		Child.prototype.constructor = Child
		Child.superclass = Parent.prototype
	},
	extend: function(obj) {
		for (var i = 1; i < arguments.length; i++) {
			for (var p in arguments[i]) {
				if (arguments[i].hasOwnProperty(p)) {
					obj[p] = arguments[i][p];
				}
			}
		}
		return obj;
	},
	hasClass: function(obj, cname) {
		return (typeof obj != "undefined" && obj && (obj.className ? obj.className.match(new RegExp("(\\s|^)" + cname + "(\\s|$)")) : false));
	},
	addClass: function(obj, cname) {
		if (typeof obj != "undefined" && obj && !this.hasClass(obj, cname))
			obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === " " ? "" : " ") + cname;
	},
	removeClass: function(obj, cname) {
		if (typeof obj != "undefined" && obj && this.hasClass(obj, cname))
			obj.className = obj.className.replace(new RegExp("(\\s|^)" + cname + "(\\s|$)"), " ").replace(/\s+$/, "");
	},
	toggleClass: function(obj, cname, condition) {
		if (condition) this.addClass(obj, cname);
		else this.removeClass(obj, cname);
	},
	createElement: function(tagName, options) {
		var el = document.createElement(tagName);
		for (var p in options) {
			if (options.hasOwnProperty(p)) {
				switch (p) {
					case "class": el.className = options[p]; break;
					case "html":
						if (jQuery) jQuery(el).html(options[p]);
						else el.innerHTML = options[p];
						break;
					case "style": this.setStyles(el, options[p]); break;
					default: el.setAttribute(p, options[p]);
				}
			}
		}
		return el;
	},
	setStyles: function(el, styles) {
		for (var p in styles) {
			if (styles.hasOwnProperty(p)) {
				switch (p) {
					case "float": el.style.cssFloat = styles[p]; break;
					case "opacity":
						el.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + styles[p] * 100 + ")";
						el.style.opacity = styles[p];
						break;
					default:
						el.style[p] = (typeof styles[p] === "undefined" ? 0 : styles[p]) + (typeof styles[p] === "number" ? "px" : "");
				}
			}
		}
		return el;
	},
	getInnerWidth: function(el) {
		return el.offsetWidth - (parseInt(this.getStyle(el, "paddingLeft")) || 0) - (parseInt(this.getStyle(el, "paddingRight")) || 0);
	},
	getInnerHeight: function(el) {
		return el.offsetHeight - (parseInt(this.getStyle(el, "paddingTop")) || 0) - (parseInt(this.getStyle(el, "paddingBottom")) || 0);
	},
	getAllClasses: function(cname, prefix, skip) {
		if (!skip) skip = "";
		if (!prefix) prefix = "";
		return cname ? cname.replace(new RegExp("(\\s|^)" + skip + "(\\s|$)"), " ").replace(/[\s]*([\S]+)+[\s]*/gi, prefix + "$1 ") : "";
	},
	getElementsBySelector: function(selector, scope) {
		if (typeof document.querySelectorAll === "function") {
			return (scope || document).querySelectorAll(selector);
		}
		else if (typeof jQuery != "undefined" && jQuery) {
			return jQuery(selector, (scope || document)).toArray();
		}

		var selectors = selector.split(',');
		var resultList = [];
		for (var s = 0; s < selectors.length; s++) {
			var currentContext = [scope || document];
			var tokens = selectors[s].replace(/^\s+/, "").replace(/\s+$/, "").split(" ");
			for (var i = 0; i < tokens.length; i++) {
				token = tokens[i].replace(/^\s+/, "").replace(/\s+$/, "");
				if (token.indexOf("#") > -1) {
					try {
						var bits = token.split("#"), tagName = bits[0], id = bits[1];
						var element = document.getElementById(id);
						if (!element.nodeName || (tagName && element.nodeName.toLowerCase() != tagName.toLowerCase())) {
							return [];
						}
						currentContext = [element];
					}
					catch(e) {
						// DEBUG
						if (typeof console != "undefined") console.log("Elements selecting error: " + e.message);
					}
					continue;
				}
				if (token.indexOf('.') > -1) {
					var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
					for (var h = 0; h < currentContext.length; h++) {
						var elements;
						if (tagName == '*') {
							elements = currentContext[h].getElementsByTagName('*');
						}
						else {
							elements = currentContext[h].getElementsByTagName(tagName);
						}
						for (var j = 0; j < elements.length; j++) {
							found[foundCount++] = elements[j];
						}
					}
					currentContext = [];
					var currentContextIndex = 0;
					for (var k = 0; k < found.length; k++) {
						if (found[k].className && found[k].className.match(new RegExp("(\\s|^)" + className + "(\\s|$)"))) {
							currentContext[currentContextIndex++] = found[k];
						}
					}
					continue;
				}
				if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
					var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
					if (attrName.toLowerCase() == "for" && this.browser.msie && this.browser.version < 8) {
						attrName = "htmlFor";
					}
					var found = [], foundCount = 0;
					for (var h = 0; h < currentContext.length; h++) {
						var elements;
						if (tagName == '*') {
							elements = currentContext[h].getElementsByTagName('*');
						}
						else {
							elements = currentContext[h].getElementsByTagName(tagName);
						}
						for (var j = 0; elements[j]; j++) {
							found[foundCount++] = elements[j];
						}
					}
					currentContext = [];
					var currentContextIndex = 0, checkFunction;
					switch (attrOperator) {
						case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
						case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp("(\\s|^)" + attrValue + "(\\s|$)"))) }; break;
						case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp("^" + attrValue + "-?"))) }; break;
						case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
						case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
						case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
						default: checkFunction = function(e) { return e.getAttribute(attrName) };
					}
					currentContext = [];
					var currentContextIndex = 0;
					for (var k = 0; k < found.length; k++) {
						if (checkFunction(found[k])) {
							currentContext[currentContextIndex++] = found[k];
						}
					}
					continue;
				}
				tagName = token;
				var found = [], foundCount = 0;
				for (var h = 0; h < currentContext.length; h++) {
					var elements = currentContext[h].getElementsByTagName(tagName);
					for (var j = 0; j < elements.length; j++) {
						found[foundCount++] = elements[j];
					}
				}
				currentContext = found;
			}
			resultList = [].concat(resultList, currentContext);
		}
		return resultList;
	},
	scrollSize: (function() {
		var content, hold, sizeBefore, sizeAfter;
		function buildSizer() {
			if (hold) removeSizer();
			content = document.createElement("div");
			hold = document.createElement("div");
			hold.style.cssText = "position:absolute;overflow:hidden;width:100px;height:100px";
			hold.appendChild(content);
			document.body.appendChild(hold);
		}
		function removeSizer() {
			document.body.removeChild(hold);
			hold = null;
		}
		function calcSize(vertical) {
			buildSizer();
			content.style.cssText = "height:" + (vertical ? "100%" : "200px");
			sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth);

			hold.style.overflow = "scroll";
			content.innerHTML = 1;
			sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth);
			if (vertical && hold.clientHeight) sizeAfter = hold.clientHeight;
			removeSizer();
			return sizeBefore - sizeAfter;
		}
		return {
			getWidth: function() {
				return calcSize(false);
			},
			getHeight: function() {
				return calcSize(true)
			}
		}
	} ()),
	domReady: function(handler) {
		var called = false
		function ready() {
			if (called) return;
			called = true;
			handler();
		}
		if (document.addEventListener) {
			document.addEventListener("DOMContentLoaded", ready, false);
		}
		else if (document.attachEvent) {
			if (document.documentElement.doScroll && window == window.top) {
				function tryScroll() {
					if (called) return
					if (!document.body) return
					try {
						document.documentElement.doScroll("left")
						ready()
					} catch (e) {
						setTimeout(tryScroll, 0)
					}
				}
				tryScroll()
			}
			document.attachEvent("onreadystatechange", function() {
				if (document.readyState === "complete") {
					ready()
				}
			})
		}
		if (window.addEventListener) window.addEventListener("load", ready, false)
		else if (window.attachEvent) window.attachEvent("onload", ready)
	},
	event: (function() {
		var guid = 0;
		function fixEvent(e) {
			e = e || window.event;
			if (e.isFixed) {
				return e;
			}
			e.isFixed = true;
			e.preventDefault = e.preventDefault || function() { this.returnValue = false }
			e.stopPropagation = e.stopPropagaton || function() { this.cancelBubble = true }
			if (!e.target) {
				e.target = e.srcElement
			}
			if (!e.relatedTarget && e.fromElement) {
				e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement;
			}
			if (e.pageX == null && e.clientX != null) {
				var html = document.documentElement, body = document.body;
				e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
				e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
			}
			if (!e.which && e.button) {
				e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0));
			}
			if (e.type === "DOMMouseScroll" || e.type === "mousewheel") {
				e.mWheelDelta = 0;
				if (e.wheelDelta) {
					e.mWheelDelta = e.wheelDelta / 120;
				}
				else if (e.detail) {
					e.mWheelDelta = -e.detail / 3;
				}
			}
			return e;
		}
		function commonHandle(event, customScope) {
			event = fixEvent(event);
			var handlers = this.events[event.type];
			for (var g in handlers) {
				var handler = handlers[g];
				var ret = handler.call(customScope || this, event);
				if (ret === false) {
					event.preventDefault()
					event.stopPropagation()
				}
			}
		}
		var publicAPI = {
			add: function(elem, type, handler, forcedScope) {
				if (elem.setInterval && (elem != window && !elem.frameElement)) {
					elem = window;
				}
				if (!handler.guid) {
					handler.guid = ++guid;
				}
				if (!elem.events) {
					elem.events = {};
					elem.handle = function(event) {
						return commonHandle.call(elem, event);
					}
				}
				if (!elem.events[type]) {
					elem.events[type] = {};
					if (elem.addEventListener) elem.addEventListener(type, elem.handle, false);
					else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle);
					if (type === "mousewheel") {
						publicAPI.add(elem, "DOMMouseScroll", handler, forcedScope);
					}
				}
				var fakeHandler = jcf.lib.bind(handler, forcedScope);
				fakeHandler.guid = handler.guid;
				elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler;
			},
			remove: function(elem, type, handler) {
				var handlers = elem.events && elem.events[type];
				if (!handlers) return;
				delete handlers[handler.guid];
				for (var any in handlers) return;
				if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false);
				else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle);
				delete elem.events[type];
				for (var any in elem.events) return;
				try {
					delete elem.handle;
					delete elem.events;
				} catch (e) {
					if (elem.removeAttribute) {
						elem.removeAttribute("handle");
						elem.removeAttribute("events");
					}
				}
				if (type === "mousewheel") {
					publicAPI.remove(elem, "DOMMouseScroll", handler);
				}
			}
		}
		return publicAPI;
	} ())
}

// init jcf styles
jcf.lib.domReady(function() {
	jcf.initStyles();
});

var $scrollbar_width = 0;
function getScrollbarWidth() {
	if ($scrollbar_width == 0) {

		var wide_scroll_html = $('<div style="width:50px;height:50px;overflow-y:scroll;position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"></div></div>')
			.prependTo($("body"));	// Append our div and add the hmtl to your document for calculations

		// Getting the width of the surrounding(parent) div - we already know it is 50px since we styled it but just to make sure.
		var scroll_w1 = wide_scroll_html.width(),
			scroll_w2 = wide_scroll_html.children("div:first").innerWidth();	// Find the inner width of the inner(child) div.

		// subtract the difference
		$scrollbar_width = scroll_w1 - scroll_w2;

		wide_scroll_html.remove();	// remove the html from your document
	}

	return $scrollbar_width;
}

// custom select module
jcf.addModule({
	name: "select",
	selector: "select:not(.editable-select)",
	defaultOptions: {
		hideDropOnScroll: true,
		showNativeDrop: false,
		handleDropPosition: true,
		selectDropPosition: "bottom", // or "top"
		wrapperClass: "select-area",
		focusClass: "select-focus",
		dropActiveClass: "select-active",
		selectedClass: "item-selected",
		currentSelectedClass: "current-selected",
		disabledClass: "select-disabled",
		valueSelector: "span.center",
		optGroupClass: "optgroup",
		openerSelector: "a.select-opener",
		selectStructure: '<span class="left"></span><span class="center"></span><a class="select-opener"></a>',
		classPrefix: "select-",
		dropMaxHeight: 200,
		dropFlippedClass: "select-options-flipped",
		dropHiddenClass: "options-hidden",
		dropScrollableClass: "options-overflow",
		dropClass: "select-options",
		dropClassPrefix: "drop-",
		dropStructure: '<div class="drop-holder"><div class="drop-list"></div></div>',
		dropSelector: "div.drop-list"
	},
	checkElement: function(el) {
		return ((!el.size || el.size == 1) && !el.multiple);
	},
	setupWrapper: function() {

		jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
		this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
		if (typeof jQuery != "undefined" && jQuery) {
			jQuery(this.fakeElement).html(this.options.selectStructure);
		}
		else {
			this.fakeElement.innerHTML = this.options.selectStructure;
		}
		this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + "px" : "auto");

		// show native drop if specified in options
		if (jcf.isTouchDevice && jcf.baseOptions.useNativeDropOnMobileDevices) {
			this.options.showNativeDrop = true;
		}
		if (this.options.showNativeDrop) {
			this.fakeElement.appendChild(this.realElement);
			jcf.lib.removeClass(this.realElement, this.options.hiddenClass);
			jcf.lib.setStyles(this.realElement, {
				top: 0,
				left: 0,
				margin: 0,
				padding: 0,
				opacity: 0,
				border: "none",
				position: "absolute",
				width: jcf.lib.getInnerWidth(this.fakeElement) - 1,
				height: jcf.lib.getInnerHeight(this.fakeElement) - 1
			});
		}

		// create select body
		this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
		this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
		jcf.lib.disableTextSelection(this.valueText);
		this.opener.jcf = this;

		// TODO: Difference with the UX 11-21-12
		var _el = jQuery(this.valueText),
			_padd = _el.outerWidth() - _el.width(),
			txtWidth = jQuery(this.fakeElement).width() - jQuery(this.opener).outerWidth() - _padd;
		_el.width(Math.floor(txtWidth));

		if (!this.options.showNativeDrop) {
			this.createDropdown();
			this.refreshState();
			this.onControlReady(this);
			this.hideDropdown(true);
		}
		else {
			this.refreshState();
		}
		this.addEvents();
	},
	addEvents: function() {
		if (this.options.showNativeDrop) {
			jcf.lib.event.add(this.realElement, "click", this.onChange, this);
		}
		else {
			jcf.lib.event.add(this.fakeElement, "click", this.toggleDropdown, this);
		}
		jcf.lib.event.add(this.realElement, "change", this.onChange, this);

		// Handle popup closing event
		var _self = this;
		jQuery(this.realElement).parents(".popup-wrapper:first, .fancybox-wrap:first")
			.bind("hide", function() { _self.hideDropdown(); });
	},
	onFakeClick: function() {
		// do nothing (drop toggles by toggleDropdown method)
	},
	onFocus: function() {
		jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
		if (!this.options.showNativeDrop) {
			// Mac Safari Fix
			if (jcf.lib.browser.safariMac) {
				this.realElement.setAttribute("size", "2");
			}
			jcf.lib.event.add(this.realElement, "keydown", this.onKeyDown, this);
			if (jcf.activeControl && jcf.activeControl != this) {
				jcf.activeControl.hideDropdown();
				jcf.activeControl = this;
			}
		}
	},
	onBlur: function() {
		if (!this.options.showNativeDrop) {
			// Mac Safari Fix
			if (jcf.lib.browser.safariMac) {
				this.realElement.removeAttribute("size");
			}
			if (!this.isActiveDrop() || !this.isOverDrop()) {
				jcf.modules[this.name].superclass.onBlur.apply(this);
				if (jcf.activeControl === this) jcf.activeControl = null;
				if (!jcf.isTouchDevice) {
					this.hideDropdown();
				}
			}
			jcf.lib.event.remove(this.realElement, "keydown", this.onKeyDown);
		}
		else {
			jcf.modules[this.name].superclass.onBlur.apply(this);
		}
	},
	onChange: function() {
		this.refreshState();
	},
	onKeyDown: function(e) {
		jcf.tmpFlag = true;
		setTimeout(function() { jcf.tmpFlag = false }, 100);

		this.keyboardFix = true;
		var context = this;
		setTimeout(function() { context.refreshState(); }, 10);

		if (e.keyCode == 13) {
			context.toggleDropdown.apply(context);
			return false;
		}
	},
	onResizeWindow: function(e) {
		if (this.isActiveDrop()) {
			this.hideDropdown();
		}
	},
	onScrollWindow: function(e) {
		if (this.options.hideDropOnScroll) {
			this.hideDropdown();
		}
		else if (this.isActiveDrop()) {
			this.positionDropdown();
		}
	},
	onOptionClick: function(e) {
		var opener = (e.target && e.target.tagName && e.target.tagName.toLowerCase() == "li")
			? e.target : jcf.lib.getParent(e.target, "li");
		if (opener) {
			this.realElement.selectedIndex = this.origSelectedIndex = parseInt(opener.getAttribute("rel"));
			if (jcf.isTouchDevice) {
				this.onFocus();
			}
			else {
				this.realElement.focus();
			}
			this.refreshState();
			this.hideDropdown();
			jcf.lib.fireEvent(this.realElement, "change");
		}
		return false;
	},
	onClickOutside: function(e) {
		if (jcf.tmpFlag) {
			jcf.tmpFlag = false;
			return;
		}
		if (!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) {
			this.hideDropdown();
		}
	},
	onDropHover: function(e) {
		if (!this.keyboardFix) {
			this.hoverFlag = true;
			var opener = (e.target && e.target.tagName && e.target.tagName.toLowerCase() == "li")
				? e.target : jcf.lib.getParent(e.target, "li");
			if (opener) {
				/*this.realElement.selectedIndex = parseInt(opener.getAttribute("rel"));
				this.refreshSelectedClass(this.realElement.selectedIndex);
				this.refreshSelectedText();*/
				this.refreshSelectedClass(parseInt(opener.getAttribute("rel")));
			}
		}
		else {
			this.keyboardFix = false;
		}
	},
	onDropLeave: function() {
		this.hoverFlag = false;
	},
	isActiveDrop: function() {
		return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
	},
	isOverDrop: function() {
		return this.hoverFlag;
	},
	createDropdown: function() {
		// remove old dropdown if exists
		if (this.selectDrop) {
			if (this.selectDrop.parentNode) {
				this.selectDrop.parentNode.removeChild(this.selectDrop);
			}
			delete this.selectDrop;
		}

		// create dropdown holder
		this.selectDrop = document.createElement("div");
		this.selectDrop.className = this.options.dropClass;
		if (jQuery) jQuery(this.selectDrop).html(this.options.dropStructure);
		else this.selectDrop.innerHTML = this.options.dropStructure;
		//
		jcf.lib.setStyles(this.selectDrop, { position: "absolute" });

		this.selectList = jcf.lib.queryBySelector(this.options.dropSelector, this.selectDrop)[0];
		this.selectDrop.jcf = this;

		jcf.lib.event.add(this.selectDrop, "click", this.onOptionClick, this);
		jcf.lib.event.add(this.selectDrop, "mouseover", this.onDropHover, this);
		jcf.lib.event.add(this.selectDrop, "mouseout", this.onDropLeave, this);

		document.body.appendChild(this.selectDrop);
		this.buildDropdown();

		jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
	},
	buildDropdown: function() {
		// build select options / optgroups
		this.buildDropdownOptions();

		// position and resize dropdown
		this.positionDropdown();

		// cut dropdown if height exceedes
		this.buildDropdownScroll();
	},
	buildDropdownOptions: function() {
		this.resStructure = "";
		this.optNum = 0;
		for (var i = 0; i < this.realElement.children.length; i++) {
			this.resStructure += this.buildElement(this.realElement.children[i]) + "\n";
		}

		if (jQuery) jQuery(this.selectList).html(this.resStructure);
		else this.selectList.innerHTML = this.resStructure;
	},
	buildDropdownScroll: function() {
		if (this.options.dropMaxHeight) {
			if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
				this.selectList.style.height = this.options.dropMaxHeight + "px";
				/*this.selectList.style.overflow = "auto";
				this.selectList.style.overflowX = "hidden";*/
				jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
			}
		}
		// DEBUG
		//console.log("h: " + this.selectList.style.height);
		jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
	},
	parseOptionTitle: function(optTitle) {
		return (typeof optTitle === "string" && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : "";
	},
	buildElement: function(obj) {
		// build option
		var res = "", optImage;
		if (obj.tagName.toLowerCase() == "option") {
			if (!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != "option") {
				res += "<ul>";
			}

			optImage = this.parseOptionTitle(obj.title);
			res += '<li rel="' + (this.optNum++) + '" class="' + (obj.className ? obj.className + " " : "") + 'jcfcalc"><a href="#">'
				+ (optImage ? '<img src="' + optImage + '" alt="" />' : "") + "<span>" + obj.innerHTML + "</span></a></li>";
			if (!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != "option") {
				res += "</ul>";
			}
			return res;
		}
		// build option group with options
		else if (obj.tagName.toLowerCase() == "optgroup" && obj.label) {
			res += '<div class="' + this.options.optGroupClass + '">';
			res += '<strong class="jcfcalc"><em>' + (obj.label) + "</em></strong>";
			for (var i = 0; i < obj.children.length; i++) {
				res += this.buildElement(obj.children[i]);
			}
			res += "</div>";
			return res;
		}
	},
	positionDropdown: function() {
		var ofs = jcf.lib.getOffset(this.fakeElement),
			selectAreaHeight = this.fakeElement.offsetHeight,
			selectDropHeight = this.selectDrop.offsetHeight;

		var wndScrollTop = jcf.lib.getScrollTop(),
			wndScrollLeft = jcf.lib.getScrollLeft(),
			wndWidth = jcf.lib.getWindowWidth(),
			wndHeight = jcf.lib.getWindowHeight(),
			fitInTop = ((ofs.top - selectDropHeight) >= wndScrollTop && (wndScrollTop + wndHeight) < (ofs.top + selectAreaHeight + selectDropHeight));


		if ((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === "top") {
			this.selectDrop.style.top = (ofs.top - selectDropHeight) + "px";
			jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass);
		}
		else {
			this.selectDrop.style.top = (ofs.top + selectAreaHeight) + "px";
			jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass);
		}
		this.selectDrop.style.left = ofs.left + "px";
		//this.selectDrop.style.width = this.fakeElement.offsetWidth + "px";

		// TODO: Calculates the dropdown width
		var width = 0,
			children = jcf.lib.queryBySelector("li", this.selectList);
		if (typeof this.calculatedWidth == "undefined" || !this.calculatedWidth) {

			var itemMaxWidth = 0;
			for (var i = 0; i < children.length; i++) {
				if (itemMaxWidth < children[i].offsetWidth) itemMaxWidth = children[i].offsetWidth;
			}

			if (this.options.dropMaxHeight) {
				if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
					itemMaxWidth += getScrollbarWidth();
				}
			}

			if (this.fakeElement.offsetWidth == 0) width = itemMaxWidth;
			else if (itemMaxWidth <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
			else if (itemMaxWidth <= this.fakeElement.offsetWidth * 2) width = itemMaxWidth;
			else width = this.fakeElement.offsetWidth * 2;

			this.calculatedWidth = width;
		}
		else {
			width = this.calculatedWidth;

			if (this.fakeElement.offsetWidth == 0) width = this.calculatedWidth;
			else if (width <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
			else if (width <= this.fakeElement.offsetWidth * 2) width = this.calculatedWidth;
			else width = this.fakeElement.offsetWidth * 2;
		}

		this.selectDrop.style.width = width + "px";

		for (var i = 0; i < children.length; i++) {
			children[i].style.width = width + "px";
		}

		if (width > this.fakeElement.offsetWidth) {
			if ((width + ofs.left) > (wndScrollLeft + wndWidth)) {
				ofs.left = ofs.left - (width - this.fakeElement.offsetWidth);
				this.selectDrop.style.left = ofs.left + "px";
			}
		}
		// End of the dropdown width re-calculating
	},
	showDropdown: function() {
		if (!this.selectDrop.parentNode || this.selectDrop.parentNode !== document.body) {
			document.body.appendChild(this.selectDrop);
		}

		jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
		jcf.lib.addClass(this.fakeElement, this.options.dropActiveClass);
		this.positionDropdown();

		// highlight current active item
		var activeItem = this.getFakeActiveOption();
		if (activeItem) {
			this.removeClassFromItems(this.options.currentSelectedClass);
			jcf.lib.addClass(activeItem, this.options.currentSelectedClass);
		}

		// show current dropdown
		jcf.lib.event.add(window, "resize", this.onResizeWindow, this);
		jcf.lib.event.add(window, "scroll", this.onScrollWindow, this);
		jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this);
		this.positionDropdown();
	},
	hideDropdown: function(partial) {
		if (this.selectDrop.parentNode && this.selectDrop.offsetWidth) {
			this.selectDrop.parentNode.removeChild(this.selectDrop);
		}

		if (typeof partial == "undefined" || !partial) {
			if (typeof this.origSelectedIndex != "undefined" && this.origSelectedIndex >= 0
				&& typeof this.realElement.selectedIndex != "undefined" && this.origSelectedIndex != this.realElement.selectedIndex) {
				// DEBUG
				if (typeof console != "undefined") {
					console.log("jcf.hideDropdown(), origSelectedIndex = " + this.origSelectedIndex
						+ ", realElement.selectedIndex = " + this.realElement.selectedIndex);
				}

				this.realElement.selectedIndex = this.origSelectedIndex;
				this.refreshSelectedText();
			}

			jcf.lib.removeClass(this.fakeElement, this.options.dropActiveClass);
			jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
			jcf.lib.event.remove(window, "resize", this.onResizeWindow);
			jcf.lib.event.remove(window, "scroll", this.onScrollWindow);
			jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside);

			if (jcf.isTouchDevice) this.onBlur();
		}
	},
	toggleDropdown: function() {
		if (!this.realElement.disabled) {
			if (jcf.isTouchDevice) {
				this.onFocus();
			}
			else {
				this.realElement.focus();
			}
			this.dropOpened = true;
			if (this.isActiveDrop()) {
				this.hideDropdown();
			}
			else {
				this.showDropdown();
			}
			this.refreshState();
		}
	},
	scrollToItem: function() {
		if (this.isActiveDrop()) {
			var dropHeight = this.selectList.offsetHeight,
				activeOption = this.getFakeActiveOption(),

				offsetTop = (!activeOption) ? 0 : this.calcOptionOffset(activeOption),
				sTop = this.selectList.scrollTop,
				oHeight = (!activeOption) ? 0 : activeOption.offsetHeight;
			//offsetTop += sTop;

			if (offsetTop >= sTop + dropHeight) {
				this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
			}
			else if (offsetTop < sTop) {
				this.selectList.scrollTop = offsetTop;
			}
		}
	},
	getFakeActiveOption: function(c) {
		if (typeof c != "number") c = this.realElement.selectedIndex;
		if (c >= 0) {
			var els = jcf.lib.queryBySelector('li[rel="' + c + '"]', this.selectList);
			if (els && typeof els.length != "undefined" && els.length) return els[0];
		}

		return null;
	},
	calcOptionOffset: function(fake) {
		var h = 0;
		var els = jcf.lib.queryBySelector(".jcfcalc", this.selectList);
		for (var i = 0; i < els.length; i++) {
			if (els[i] == fake) break;
			h += els[i].offsetHeight;
		}
		return h;
	},
	childrenHasItem: function(hold, item) {
		var items = hold.getElementsByTagName('*');
		for (i = 0; i < items.length; i++) {
			if (items[i] == item) return true;
		}
		return false;
	},
	removeClassFromItems: function(className) {
		var children = jcf.lib.queryBySelector("li", this.selectList);
		for (var i = children.length - 1; i >= 0; i--) {
			jcf.lib.removeClass(children[i], className);
		}
	},
	setSelectedClass: function(c) {
		var activeOption = this.getFakeActiveOption(c);
		if (activeOption) {
			jcf.lib.addClass(activeOption, this.options.selectedClass);
		}
	},
	refreshSelectedClass: function(c) {
		if (!this.options.showNativeDrop) {
			this.removeClassFromItems(this.options.selectedClass);
			this.setSelectedClass(c);
		}
		if (this.realElement.disabled) {
			jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
			if (this.labelFor) {
				jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
			}
		}
		else {
			jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
			if (this.labelFor) {
				jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
			}
		}
	},
	refreshSelectedText: function() {
		if (!this.dropOpened && this.realElement.title) {
			if (jQuery) jQuery(this.valueText).text(this.realElement.title);
			else this.valueText.innerHTML = this.realElement.title;
		}
		else if (this.realElement && this.realElement.options) {
			if (!this.realElement.options.length) {
				if (jQuery) jQuery(this.valueText).empty();
				else this.valueText.innerHTML = "";
			}
			else {
				// DEBUG
				//if (typeof console != "undefined")
				//	console.log("jcf.refreshSelectedText(), realElement.selectedIndex = " + this.realElement.selectedIndex);

				var selectedIdx = (typeof this.realElement.selectedIndex != "undefined" && this.realElement.selectedIndex >= 0)
						? this.realElement.selectedIndex : 0,
					elOpt = this.realElement.options[selectedIdx];

				if (typeof elOpt.title != "undefined" && elOpt.title) {
					var optImage = this.parseOptionTitle(elOpt.title);

					if (jQuery) jQuery(this.valueText).html((optImage ? '<img src="' + optImage + '" alt="" />' : "") + jQuery(elOpt).html());
					else this.valueText.innerHTML = (optImage ? '<img src="' + optImage + '" alt="" />' : "") + elOpt.innerHTML;
				}
				else {
					if (jQuery) jQuery(this.valueText).html(jQuery(elOpt).html());
					else this.valueText.innerHTML = elOpt.innerHTML;
				}
			}
		}
	},
	refreshState: function() {
		// DEBUG
		//if (typeof console != "undefined")
		//	console.log("jcf.refreshState(), realElement.selectedIndex = " + this.realElement.selectedIndex);

		this.origSelectedIndex = this.realElement.selectedIndex;
		this.refreshSelectedClass();
		this.refreshSelectedText();

		if (!this.options.showNativeDrop) {
			this.positionDropdown();
			if (this.selectDrop.offsetWidth) this.scrollToItem();
		}
	}
});


// mobile browsers detect
browserPlatform = {
	platforms: [
		{ uaString: ["symbian", "midp"], cssFile: "symbian.css" },	// Symbian phones
		{ uaString: ["opera", "mobi"], cssFile: "opera.css" },		// Opera Mobile
		{ uaString: ["msie", "ppc"], cssFile: "ieppc.css" },		// IE Mobile <6
		{ uaString: "iemobile", cssFile: "iemobile.css" },			// IE Mobile 6+
		{ uaString: "webos", cssFile: "webos.css" },				// Palm WebOS
		{ uaString: "Android", cssFile: "android.css" },			// Android
		{ uaString: ["BlackBerry", "/6.0", "mobi"], cssFile: "blackberry6.css" },	// Blackberry 6
		{ uaString: ["BlackBerry", "/7.0", "mobi"], cssFile: "blackberry7.css" },	// Blackberry 7+
		{ uaString: "ipad", cssFile: "ipad.css", miscHead: '<meta name="viewport" content="width=950" />' },			// iPad
		{ uaString: ["safari", "mobi"], cssFile: "safari.css", miscHead: '<meta name="viewport" content="width=950" />'}// iPhone and other webkit browsers
	],
	options: {
		cssPath: "css/",
		mobileCSS: "allmobile.css"
	},
	init: function() {
		this.checkMobile();
		this.parsePlatforms();
		return this;
	},
	checkMobile: function() {
		if (this.uaMatch("mobi") || this.uaMatch("midp") || this.uaMatch("ppc") || this.uaMatch("webos")) {
			this.attachStyles({ cssFile: this.options.mobileCSS });
		}
	},
	parsePlatforms: function() {
		for (var i = 0; i < this.platforms.length; i++) {
			if (typeof this.platforms[i].uaString === "string") {
				if (this.uaMatch(this.platforms[i].uaString)) {
					this.attachStyles(this.platforms[i]);
					break;
				}
			}
			else {
				for (var j = 0, allMatch = true; j < this.platforms[i].uaString.length; j++) {
					if (!this.uaMatch(this.platforms[i].uaString[j])) {
						allMatch = false;
					}
				}
				if (allMatch) {
					this.attachStyles(this.platforms[i]);
					break;
				}
			}
		}
	},
	attachStyles: function(platform) {
		var head = document.getElementsByTagName("head")[0],
			fragment,
			cssText = '<link rel="stylesheet" href="' + this.options.cssPath + platform.cssFile + '" type="text/css" />',
			miscText = platform.miscHead;

		if (platform.cssFile) {
			if (document.body) {
				fragment = document.createElement("div");
				fragment.innerHTML = cssText;
				head.appendChild(fragment.childNodes[0]);
			}
			else {
				document.write(cssText);
			}
		}
		if (platform.miscHead) {
			if (document.body) {
				fragment = document.createElement("div");
				fragment.innerHTML = miscText;
				head.appendChild(fragment.childNodes[0]);
			}
			else {
				document.write(miscText);
			}
		}
	},
	uaMatch: function(str) {
		if (typeof this.ua == "undefined" || !this.ua) {
			this.ua = navigator.userAgent.toLowerCase();
		}
		return this.ua.indexOf(str.toLowerCase()) != -1;
	}
}.init();



/*
  jQuery Tooltip - Dimensions
*/
(function($) {

// store a copy of the core height and width methods
var oldHeight	= $.fn.height,
	oldWidth	= $.fn.width,
	//oldOffset	= $.fn.offset,
	oldPosition	= $.fn.position,
	oldHide		= $.fn.hide;

$.fn.extend({
	hide: function(duration, easing, callback) {
		if ($(this).is(":visible")) $(this).trigger("hide");

		return oldHide.apply(this, arguments);
	},

	/**
	 * If used on document, returns the document's height (innerHeight)
	 * If used on window, returns the viewport's (window) height
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").height()
	 * @result 200
	 *
	 * @example $(document).height()
	 * @result 800
	 *
	 * @example $(window).height()
	 * @result 400
	 *
	 * @name height
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	height: function() {
		if (this.get(0) == window) {
			return (self.innerHeight
				|| $.boxModel && document.documentElement.clientHeight
				|| document.body.clientHeight);
		}

		if (this.get(0) == document) {
			return Math.max(document.body.scrollHeight, document.body.offsetHeight);
		}

		return oldHeight.apply(this, arguments);
	},

	/**
	 * If used on document, returns the document's width (innerWidth)
	 * If used on window, returns the viewport's (window) width
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").width()
	 * @result 200
	 *
	 * @example $(document).width()
	 * @result 800
	 *
	 * @example $(window).width()
	 * @result 400
	 *
	 * @name width
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	width: function() {
		if (this.get(0) == window) {
			return (self.innerWidth
				|| $.boxModel && document.documentElement.clientWidth
				|| document.body.clientWidth);
		}

		if (this.get(0) == document) {
			return Math.max(document.body.scrollWidth, document.body.offsetWidth);
		}

		return oldWidth.apply(this, arguments);
	},

	/**
	 * Returns the inner height value (without border) for the first matched element.
	 * If used on document, returns the document's height (innerHeight)
	 * If used on window, returns the viewport's (window) height
	 *
	 * @example $("#testdiv").innerHeight()
	 * @result 800
	 *
	 * @name innerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerHeight: function() {
		return (this.get(0) == window || this.get(0) == document) ? this.height()
			: (this.is(":visible")
				? (this.get(0).offsetHeight - num(this, "borderTopWidth") - num(this, "borderBottomWidth"))
				: (this.height() + num(this, "paddingTop") + num(this, "paddingBottom")));
	},

	/**
	 * Returns the inner width value (without border) for the first matched element.
	 * If used on document, returns the document's Width (innerWidth)
	 * If used on window, returns the viewport's (window) width
	 *
	 * @example $("#testdiv").innerWidth()
	 * @result 1000
	 *
	 * @name innerWidth
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerWidth: function() {
		return (this.get(0) == window || this.get(0) == document) ? this.width()
			: (this.is(":visible")
				? (this.get(0).offsetWidth - num(this, "borderLeftWidth") - num(this, "borderRightWidth"))
				: (this.width() + num(this, "paddingLeft") + num(this, "paddingRight")));
	},

	/**
	 * Returns the outer height value (including border) for the first matched element.
	 * Cannot be used on document or window.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 1000
	 *
	 * @name outerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	outerHeight: function() {
		return (this.get(0) == window || this.get(0) == document) ? this.height()
			: (this.is(":visible") ? this.get(0).offsetHeight
				: (this.height() + num(this, "borderTopWidth") + num(this, "borderBottomWidth") + num(this, "paddingTop") + num(this, "paddingBottom")));
	},

	/**
	 * Returns the outer width value (including border) for the first matched element.
	 * Cannot be used on document or window.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 1000
	 *
	 * @name outerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	outerWidth: function() {
		return (this.get(0) == window || this.get(0) == document) ? this.width()
			: (this.is(":visible") ? this.get(0).offsetWidth
				: (this.width() + num(this, "borderLeftWidth") + num(this, "borderRightWidth") + num(this, "paddingLeft") + num(this, "paddingRight")));
	},

	/**
	 * Returns how many pixels the user has scrolled to the right (scrollLeft).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollLeft property and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollLeft(10).scrollLeft()
	 * @result 10
	 *
	 * @name scrollLeft
	 * @param Number value A positive number representing the desired scrollLeft.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollLeft: function(val) {
		if (typeof val != "undefined") {
			// set the scroll left
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo(val, $(window).scrollTop());
				else
					this.scrollLeft = val;
			});
		}

		// return the scroll left offest in pixels
		if (this.get(0) == window || this.get(0) == document) {
			return (self.pageXOffset
				|| $.boxModel && document.documentElement.scrollLeft
				|| document.body.scrollLeft);
		}

		return this.get(0).scrollLeft;
	},

	/**
	 * Returns how many pixels the user has scrolled to the bottom (scrollTop).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollTop property and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollTop(10).scrollTop()
	 * @result 10
	 *
	 * @name scrollTop
	 * @param Number value A positive number representing the desired scrollTop.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollTop: function(val) {
		if (typeof val != "undefined") {
			// set the scroll top
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo($(window).scrollLeft(), val);
				else
					this.scrollTop = val;
			});
		}

		// return the scroll top offset in pixels
		if (this.get(0) == window || this.get(0) == document) {
			return (self.pageYOffset
				|| $.boxModel && document.documentElement.scrollTop
				|| document.body.scrollTop);
		}

		return this.get(0).scrollTop;
	},

	/**
	 * Returns the top and left positioned offset in pixels.
	 * The positioned offset is the offset between a positioned
	 * parent and the element itself.
	 *
	 * @example $("#testdiv").position()
	 * @result { top: 100, left: 100 }
	 *
	 * @name position
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? False by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	position: function(options, returnObject) {
		options = $.extend({ margin: false, border: false, padding: false, scroll: false }, options || {});

		var elem = this.get(0),
			x = elem.offsetLeft,
			y = elem.offsetTop,
			sl = elem.scrollLeft,
			st = elem.scrollTop;
		// DEBUG
		//if (typeof console != "undefined")
		//	console.log("position(), :: elem = " + elem + ", x = " + x + ", y = " + y + ", sl = " + sl + ", st = " + st);

		// Mozilla and IE do not add the border
		if ($.browser.mozilla || $.browser.msie) {
			// add borders to offset
			x += num(elem, "borderLeftWidth");
			y += num(elem, "borderTopWidth");
		}

		if ($.browser.mozilla) {
			var parent = elem.parentNode,
				op = elem.offsetParent;

			while (parent) {
				// Mozilla does not add the border for a parent that has overflow set to anything but visible
				if ($.browser.mozilla && parent != elem && $.css(parent, "overflow") != "visible") {
					x += num(parent, "borderLeftWidth");
					y += num(parent, "borderTopWidth");
				}

				if (parent == op) break;	// break if we are already at the offestParent
				parent = parent.parentNode;

				if (parent && parent.tagName
					&& (parent.tagName.toLowerCase() == "body" || parent.tagName.toLowerCase() == "html")) {
					break;
				}
			}
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
		// DEBUG
		if (typeof console != "undefined") {
			var expectedVal = oldPosition.apply(this, arguments);

			if (Math.abs(expectedVal.top - returnValue.top) > 2 || Math.abs(expectedVal.left - returnValue.left) > 2) {
				console.log("jQuery.position(), [WARN] returnValue = " + JSON.stringify(returnValue) + ", expectedValue = " + JSON.stringify(expectedVal));
			}
		}

		if (typeof returnObject != "undefined" && returnObject) {
			$.extend(returnObject, returnValue);
			return this;
		}

		return returnValue;
	},

	/**
	 * Returns the location of the element in pixels from the top left corner of the viewport.
	 *
	 * For accurate readings make sure to use pixel values for margins, borders and padding.
	 *
	 * Known issues:
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
	 *
	 * @example $("#testdiv").offset()
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
	 *
	 * @example $("#testdiv").offset({ scroll: false })
	 * @result { top: 90, left: 90 }
	 *
	 * @example var offset = {}
	 * $("#testdiv").offset({ scroll: false }, offset)
	 * @result offset = { top: 90, left: 90 }
	 *
	 * @name offset
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                        When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
	 *                        to the returned object, scrollTop and scrollLeft.
	 * @options Boolean lite Will use offsetLite instead of offset when set to true. False by default.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	/*offset: function(options, returnObject) {
		options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false }, options || {});

		var elem = this.get(0),
			x = 0, y = 0, sl = 0, st = 0,
			mo = $.browser.mozilla, ie = $.browser.msie, sf = $.browser.safari, oa = $.browser.opera;
		// DEBUG
		//if (typeof console != "undefined") console.log("offset(), :: elem = " + elem);

		// Use offsetLite if lite option is true
		if (options.lite) return this.offsetLite(options, returnObject);

		if (elem.tagName && (elem.tagName.toLowerCase() == "body" || elem.tagName.toLowerCase() == "html")) {
			// Safari is the only one to get offsetLeft and offsetTop properties of the body "correct"
			// Except they all mess up when the body is positioned absolute or relative
			x = elem.offsetLeft;
			y = elem.offsetTop;

			// Mozilla ignores margin and subtracts border from body element
			if (mo) {
				x += num(elem, "marginLeft") + (num(elem, "borderLeftWidth")*2);
				y += num(elem, "marginTop")  + (num(elem, "borderTopWidth") *2);
			}
			else if (oa) {						// Opera ignores margin
				x += num(elem, "marginLeft");
				y += num(elem, "marginTop");
			}
			else if (ie && jQuery.boxModel) {	// IE does not add the border in Standards Mode
				x += num(elem, "borderLeftWidth");
				y += num(elem, "borderTopWidth");
			}
		}
		else {
			var elemPos = $.css(elem, "position"),
				parent = elem, parPos, op, pos,
				absparent = false, relparent = false;

			while (parent) {
				parPos = $.css(parent, "position");

				x += parent.offsetLeft;
				y += parent.offsetTop;

				// Mozilla and IE do not add the border
				if (mo || ie) {
					// add borders to offset
					x += num(parent, "borderLeftWidth");
					y += num(parent, "borderTopWidth");

					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					if (mo && parPos == "absolute") absparent = true;
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
					if (ie && parPos == "relative") relparent = true;
				}

				op = parent.offsetParent;
				if (options.scroll || mo) {
					while (parent && parent != op) {
						// get scroll offsets
						if (options.scroll) {
							if (typeof parent.scrollLeft != "undefined" && !isNaN(pos = parseInt(parent.scrollLeft))) sl += pos;
							if (typeof parent.scrollTop != "undefined" && !isNaN(pos = parseInt(parent.scrollTop))) st += pos;
						}

						// Mozilla does not add the border for a parent that has overflow set to anything but visible
						if (mo && parent != elem && $.css(parent, "overflow") != "visible") {
							x += num(parent, "borderLeftWidth");
							y += num(parent, "borderTopWidth");
						}

						parent = parent.parentNode;
					}
				}
				parent = op;

				if (parent && parent.tagName && (parent.tagName.toLowerCase() == "body" || parent.tagName.toLowerCase() == "html")) {
					// Safari and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
					if ((sf || (ie && $.boxModel)) && elemPos != "absolute" && elemPos != "fixed") {
						x += num(parent, "marginLeft");
						y += num(parent, "marginTop");
					}
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
					if ((mo && !absparent && elemPos != "fixed") || (ie && elemPos == "static" && !relparent)) {
						x += num(parent, "borderLeftWidth");
						y += num(parent, "borderTopWidth");
					}

					break; // Exit the loop
				}
			}
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
		// DEBUG
		if (typeof console != "undefined") {
			var expectedVal = oldOffset.apply(this, arguments);

			if (Math.abs(expectedVal.top - returnValue.top) > 2 || Math.abs(expectedVal.left - returnValue.left) > 2) {
				console.log("jQuery.offset(), [WARN] returnValue = " + JSON.stringify(returnValue) + ", expectedValue = " + JSON.stringify(expectedVal));
			}
		}

		if (returnObject) {
			$.extend(returnObject, returnValue);
			return this;
		}

		return returnValue;
	},*/

	/**
	 * Returns the location of the element in pixels from the top left corner of the viewport.
	 * This method is much faster than offset but not as accurate. This method can be invoked
	 * by setting the lite option to true in the offset method.
	 *
	 * @name offsetLite
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                        When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
	 *                        to the returned object, scrollTop and scrollLeft.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offsetLite: function(options, returnObject) {
		options = $.extend({ margin: true, border: false, padding: false, scroll: true }, options || {});

		var x = 0, y = 0, sl = 0, st = 0,
			parent = this.get(0), op, pos;
		// DEBUG
		//if (typeof console != "undefined") console.log("offsetLite(), :: parent = " + parent);

		while (parent) {
			x += parent.offsetLeft;
			y += parent.offsetTop;

			op = parent.offsetParent;
			if (options.scroll) {
				// get scroll offsets
				while (parent && parent != op) {
					if (typeof parent.scrollLeft != "undefined" && !isNaN(pos = parseInt(parent.scrollLeft))) sl += pos;
					if (typeof parent.scrollTop != "undefined" && !isNaN(pos = parseInt(parent.scrollTop))) st += pos;

					parent = parent.parentNode;
				}
			}
			parent = op;

			if (parent && parent.tagName
				&& (parent.tagName.toLowerCase() == "body" || parent.tagName.toLowerCase() == "html")) {
				break;
			}
		}

		var returnValue = handleOffsetReturn(this.get(0), options, x, y, sl, st);

		if (typeof returnObject != "undefined" && returnObject) {
			$.extend(returnObject, returnValue);
			return this;
		}

		return returnValue;
	}
});

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
	var cssVal = $.css(el.jquery ? el.get(0) : el, prop);
	if (typeof cssVal != "undefined" && (cssVal = $.trim(cssVal)) != "") {

		cssVal = parseInt( cssVal.replace(/[^\d]+$/, "").replace(/^[^\d\-\+]+/, "") );
		if (!isNaN(cssVal)) return cssVal;
	}

	return 0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
	// DEBUG
	//if (typeof console != "undefined")
	//	console.log("handleOffsetReturn(), >> elem = " + elem + ", x = " + x + ", y = " + y + ", sl = " + sl + ", st = " + st);

	if (!options.margin) {
		x -= num(elem, "marginLeft");
		y -= num(elem, "marginTop");
	}

	// Safari and Opera do not add the border for the element
	if (options.border && ($.browser.safari || $.browser.opera)) {
		x += num(elem, "borderLeftWidth");
		y += num(elem, "borderTopWidth");
	}
	else if (!options.border && !($.browser.safari || $.browser.opera)) {
		x -= num(elem, "borderLeftWidth");
		y -= num(elem, "borderTopWidth");
	}

	if (options.padding) {
		x += num(elem, "paddingLeft");
		y += num(elem, "paddingTop");
	}

	// do not include scroll offset on the element
	var pos = 0;
	if (options.scroll) {
		if (typeof elem.scrollLeft != "undefined" && !isNaN(pos = parseInt(elem.scrollLeft))) sl -= pos;
		if (typeof elem.scrollTop != "undefined" && !isNaN(pos = parseInt(elem.scrollTop))) st -= pos;
	}

	return (!options.scroll) ? { top: y, left: x }
		: { top: y + st, left: x + sl, scrollTop:  st, scrollLeft: sl };
};

})(jQuery);

/*
  jQuery Tooltip - BGiframe
*/
(function($) {
$.fn.bgIframe = $.fn.bgiframe = function(s) {
	// This is only for IE6
	if ($.browser.msie && parseInt($.browser.version) <= 6) {
		s = $.extend({
			top:		"auto",	// auto == .currentStyle.borderTopWidth
			left:		"auto",	// auto == .currentStyle.borderLeftWidth
			width:		"auto",	// auto == offsetWidth
			height:		"auto",	// auto == offsetHeight
			opacity:	true,
			src:		"javascript:false;"
		}, s || {});

		var prop = function(n) { return n && n.constructor == Number ? n + "px" : n; },
			html = '<iframe class="bgiframe" frameborder="0" tabindex="-1" src="' + s.src
					+ '" style="display:block; position:absolute; z-index:-1;'
						+ ((!s.opacity) ? "" : " filter:Alpha(Opacity='0');")
						+ " top:" + (s.top == "auto" ? "expression(((parseInt(this.parentNode.currentStyle.borderTopWidth) || 0) * (-1)) + 'px')" : prop(s.top))
						+ "; left:" + (s.left == "auto" ? "expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth) || 0) * (-1)) + 'px')" : prop(s.left))
						+ "; width:" + (s.width == "auto" ? "expression(this.parentNode.offsetWidth + 'px')" : prop(s.width))
						+ "; height:" + (s.height == "auto" ? "expression(this.parentNode.offsetHeight + 'px')" : prop(s.height))
						+ ';" />';

		return this.each(function() {
			if (!$("> iframe.bgiframe", this).length)
				this.insertBefore(document.createElement(html), this.firstChild);
		});
	}

	return this;
};

// Add browser.version if it doesn't exist
if (!$.browser.version)
	$.browser.version = navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1];

})(jQuery);

/*
 * jQuery Tooltip plugin 1.3
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
 * http://docs.jquery.com/Plugins/Tooltip
 *
 * Copyright (c) 2006 - 2008 Jörn Zaefferer
 *
 * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */;(function($){var helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,fade:false,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return this.each(function(){$.data(this,"tooltip",settings);this.tOpacity=helper.parent.css("opacity");this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).mouseover(save).mouseout(hide).click(hide);},fixPNG:IE?function(){return this.each(function(){var image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"}).each(function(){var position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return this;},unfixPNG:IE?function(){return this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return this;},hideWhenEmpty:function(){return this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return this.attr('href')||this.attr('src');}});function createHelper(settings){if(helper.parent)return;helper.parent=$('<div id="'+settings.id+'"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function settings(element){return $.data(element,"tooltip");}function handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else if(settings(this).showBody){var parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var i=0,part;(part=parts[i]);i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function show(){tID=null;if((!IE||!$.fn.bgiframe)&&settings(current).fade){if(helper.parent.is(":animated"))helper.parent.stop().show().fadeTo(settings(current).fade,current.tOpacity);else
helper.parent.is(':visible')?helper.parent.fadeTo(settings(current).fade,current.tOpacity):helper.parent.fadeIn(settings(current).fade);}else{helper.parent.show();}update();}function update(event){if($.tooltip.blocked)return;if(event&&event.target&&event.target.tagName&&event.target.tagName.toLowerCase()=="option"){return;}if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var left=helper.parent[0].offsetLeft;var top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;var right='auto';if(settings(current).positionLeft){right=$(window).width()-left;left='auto';}helper.parent.css({left:left,right:right,top:top});}var v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;var tsettings=settings(this);function complete(){helper.parent.removeClass(tsettings.extraClass).hide().css("opacity","");}if((!IE||!$.fn.bgiframe)&&tsettings.fade){if(helper.parent.is(':animated'))helper.parent.stop().fadeTo(tsettings.fade,0,complete);else
helper.parent.stop().fadeOut(tsettings.fade,complete);}else
complete();if(settings(this).fixPNG)helper.parent.unfixPNG();}})(jQuery);
